<template>
  <div class="match-game">
    <div class="mg-head">
  <div class="mg-tip">从左、右两列中各选择一项组成配对；全部正确后即可完成。</div>
      <div class="mg-stats">
  <el-tag size="small" type="success">已配对：{{ matchedPairs.length }}/{{ totalPairs }}</el-tag>
        <el-tag size="small" type="info">尝试：{{ attempts }}</el-tag>
      </div>
    </div>
    <div class="mg-body">
      <div class="col">
        <div class="col-title">左侧</div>
        <ul class="list">
          <li v-for="(l, idx) in leftList" :key="'L-'+idx"
              :class="['item', { selected: selectedLeft===l, disabled: isLeftPaired(l) }]"
              @click="onSelectLeft(l)">{{ l }}</li>
        </ul>
      </div>
      <div class="col">
        <div class="col-title">右侧</div>
        <ul class="list">
          <li v-for="(r, idx) in rightList" :key="'R-'+idx"
              :class="['item', { selected: selectedRight===r, disabled: isRightPaired(r) }]"
              @click="onSelectRight(r)">{{ r }}</li>
        </ul>
      </div>
    </div>
    <div class="mg-actions">
      <el-button size="small" @click="undoLast" :disabled="matchedPairs.length===0">撤销上一步</el-button>
      <el-button size="small" @click="resetAll" :disabled="matchedPairs.length===0">重置</el-button>
    </div>
    <div class="mg-pairs" v-if="matchedPairs.length">
      <div class="pair" v-for="(p,i) in matchedPairs" :key="i">{{ p.left }} ＝ {{ p.right }}</div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'

const props = defineProps({
  quest: { type: Object, required: true }
})
const emit = defineEmits(['progress', 'canFinishChanged'])

const selectedLeft = ref(null)
const selectedRight = ref(null)
const matchedPairs = ref([]) // [{left,right}]
const attempts = ref(0)

const totalPairs = computed(() => Array.isArray(props.quest?.requirement_json?.items) ? props.quest.requirement_json.items.length : 0)
const leftList = computed(() => {
  const items = props.quest?.requirement_json?.items || []
  return items.map(i => String(i?.left ?? '')).filter(Boolean)
})
const rightList = computed(() => {
  const items = props.quest?.requirement_json?.items || []
  // 打乱以防与左侧一一相同顺序
  const arr = items.map(i => String(i?.right ?? '')).filter(Boolean)
  return shuffle(arr)
})

function shuffle(a) { const b = [...a]; for (let i=b.length-1;i>0;i--){ const j=Math.floor(Math.random()*(i+1)); [b[i],b[j]]=[b[j],b[i]] } return b }

function isLeftPaired(l){ return matchedPairs.value.some(p => p.left===l) }
function isRightPaired(r){ return matchedPairs.value.some(p => p.right===r) }

function onSelectLeft(l){ if(isLeftPaired(l)) return; selectedLeft.value = (selectedLeft.value===l ? null : l); tryPair() }
function onSelectRight(r){ if(isRightPaired(r)) return; selectedRight.value = (selectedRight.value===r ? null : r); tryPair() }

function tryPair(){
  if(selectedLeft.value && selectedRight.value){
    matchedPairs.value.push({ left: selectedLeft.value, right: selectedRight.value })
    attempts.value += 1
    selectedLeft.value = null
    selectedRight.value = null
    report()
  }
}

function undoLast(){
  if(matchedPairs.value.length){ matchedPairs.value.pop(); report() }
}
function resetAll(){ matchedPairs.value = []; attempts.value = 0; selectedLeft.value=null; selectedRight.value=null; report() }

function computeCorrect(){
  const items = props.quest?.requirement_json?.items || []
  const ans = new Set(items.map(it => `${String(it.left).trim()}@@${String(it.right).trim()}`))
  let c = 0
  matchedPairs.value.forEach(p => { const k = `${String(p.left).trim()}@@${String(p.right).trim()}`; if(ans.has(k)) c++ })
  return c
}

function report(){
  const payload = {
    matched: matchedPairs.value,
    correct: computeCorrect(),
    attempts: attempts.value
  }
  emit('progress', payload)
  const canFinish = matchedPairs.value.length >= totalPairs.value && payload.correct >= totalPairs.value
  emit('canFinishChanged', canFinish)
}

onMounted(() => {
  // 若后端存在回显进度，可在此恢复（简化忽略，依赖刷新即可）
  report()
})

watch(() => props.quest?.id, () => { resetAll() })
</script>

<style scoped>
.match-game { display:block; }
.mg-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:6px; }
.mg-tip { color:#666; font-size:12px; }
.mg-stats { display:flex; gap:6px; }
.mg-body { display:grid; grid-template-columns: 1fr 1fr; gap:10px; }
.col { background: rgba(255,255,255,.78); border:1px solid rgba(0,0,0,.06); border-radius:8px; padding:8px; }
.col-title { font-weight:600; margin-bottom:6px; }
.list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:6px; }
.item { padding:8px 10px; border-radius:8px; background:#f6f8fa; cursor:pointer; user-select:none; transition: all .15s ease; }
.item.selected { outline:2px solid #409eff; background:#eef5ff; }
.item.disabled { opacity:.5; pointer-events:none; }
.mg-actions { margin-top:8px; display:flex; gap:8px; }
.mg-pairs { margin-top:8px; color:#444; font-size:13px; }
.pair { padding:2px 0; }
</style>
